# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.

[build-system]
requires = ["hatchling>=1.21.1"]
build-backend = "hatchling.build"

[project]
name = "jupyterlab"
description = "JupyterLab computational environment"
readme = "README.md"
license = { file = "LICENSE" }
requires-python = ">=3.8"
authors = [
    { name = "Jupyter Development Team", email = "jupyter@googlegroups.com" },
]
keywords = [
    "ipython",
    "jupyter",
]
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Framework :: Jupyter",
    "Framework :: Jupyter :: JupyterLab",
    "Framework :: Jupyter :: JupyterLab :: 4",
    "Intended Audience :: Developers",
    "Intended Audience :: Science/Research",
    "Intended Audience :: System Administrators",
    "License :: OSI Approved :: BSD License",
    "Programming Language :: Python",
    "Programming Language :: Python :: 3.8",
    "Programming Language :: Python :: 3.9",
    "Programming Language :: Python :: 3.10",
    "Programming Language :: Python :: 3.11",
]
dependencies = [
    "async_lru>=1.0.0",
    "httpx>=0.25.0",
    "importlib-metadata>=4.8.3;python_version<\"3.10\"",
    "importlib-resources>=1.4;python_version<\"3.9\"",
    "ipykernel",
    "jinja2>=3.0.3",
    "jupyter_core",
    "jupyter_server>=2.4.0,<3",
    "jupyter-lsp>=2.0.0",
    "jupyterlab_server>=2.19.0,<3",
    "notebook_shim>=0.2",
    "packaging",
    "tomli;python_version<\"3.11\"",
    "tornado>=6.2.0",
    "traitlets",
]
dynamic = [
    "version",
]

[project.scripts]
jlpm = "jupyterlab.jlpmapp:main"
jupyter-lab = "jupyterlab.labapp:main"
jupyter-labextension = "jupyterlab.labextensions:main"
jupyter-labhub = "jupyterlab.labhubapp:main"

[project.entry-points."jupyterlab.extension_manager_v1"]
readonly = "jupyterlab.extensions:get_readonly_manager"
pypi = "jupyterlab.extensions:get_pypi_manager"

[project.urls]
Homepage = "https://jupyter.org"
Changelog = "https://jupyterlab.readthedocs.io/en/stable/getting_started/changelog.html"
Documentation = "https://jupyterlab.readthedocs.io"
Source = "https://github.com/jupyterlab/jupyterlab"
Issues = "https://github.com/jupyterlab/jupyterlab/issues/new/choose"
Gitter = "https://gitter.im/jupyterlab/jupyterlab"
Pypi = "https://pypi.org/project/jupyterlab"

[project.optional-dependencies]
docs = [
    "sphinx>=1.8,<7.3.0",
    "sphinx-copybutton",
    "pydata-sphinx-theme>=0.13.0",
    "pytest",
    "pytest-jupyter",
    "pytest-check-links",
    "jsx-lexer",
    "myst-parser",
]
docs-screenshots = [
    "altair==5.2.0",
    "ipython==8.16.1",
    "ipywidgets==8.1.1",
    "jupyterlab-geojson==3.4.0",
    "jupyterlab-language-pack-zh-CN==4.0.post6",
    "matplotlib==3.8.2",
    "nbconvert>=7.0.0",
    "pandas==2.2.0",
    "scipy==1.12.0",
    "vega_datasets==0.9.0",
]
test = [
    "coverage",
    "pytest>=7.0",
    "pytest-check-links>=0.7",
    "pytest-console-scripts",
    "pytest-cov",
    "pytest-jupyter>=0.5.3",
    "pytest-timeout",
    "pytest-tornasync",
    "requests",
    "requests_cache",
    "virtualenv",
]
# Check ruff version is aligned with the one in .pre-commit-config.yaml
dev = [
    "build",
    "pre-commit",
    "pytest-cov",
    "coverage",
    "hatch",
    "bump2version",
    "ruff==0.2.0",
]

[tool.check-wheel-contents]
ignore = ["W002", "W004"]

[tool.hatch.version]
path = "jupyterlab/_version.py"
source = "code"

[tool.hatch.build.targets.wheel.shared-data]
"jupyterlab/static" = "share/jupyter/lab/static"
"jupyterlab/schemas" = "share/jupyter/lab/schemas"
"jupyterlab/themes" = "share/jupyter/lab/themes"
"jupyter-config" = "etc/jupyter"
"jupyterlab.svg" = "share/icons/hicolor/scalable/apps/jupyterlab.svg"
"jupyterlab.desktop" = "share/applications/jupyterlab.desktop"

[tool.hatch.build]
ignore-vcs = true

[tool.hatch.build.targets.sdist]
include = [
    "/*.md",
    "/buildapi.py",
    "/conftest.py",
    "/docs",
    "/docker",
    "/Dockerfile",
    "/.dockerignore",
    "/galata",
    "/jupyter-config",
    "/jupyterlab",
    "/package.json",
    "jupyterlab.svg",
    "jupyterlab.desktop"
]
exclude = [
    "/.github",
    "*.js.map",
    "node_modules",
    "/clean.py",
    "/binder",
    "/builder",
    "/buildutils",
    "/dist",
    "/docs/build",
    "/docs/source/api",
    "/design",
    "/dev_mode",
    "/examples",
    "/galata/lib",
    "/jupyterlab/staging/build",
    "/jupyterlab/staging/.yarn",
    "/packages",
    "/release",
    "/testutils",
    "/typedoc-theme"
]

[tool.hatch.build.targets.wheel]
include = [
    "/jupyterlab",
]
exclude = [
    "*.js.map",
    "/jupyterlab/staging/build",
    "/jupyterlab/staging/.yarn",
    "node_modules"
]

[tool.hatch.build.hooks.jupyter-builder]
dependencies = ["hatch-jupyter-builder>=0.3.2"]
build-function = "buildapi.builder"
ensured-targets = [
    "jupyterlab/static/package.json",
    "jupyterlab/schemas/@jupyterlab/shortcuts-extension/shortcuts.json",
    "jupyterlab/themes/@jupyterlab/theme-light-extension/index.css"
]
install-pre-commit-hook = true

[tool.hatch.build.hooks.jupyter-builder.editable-build-kwargs]
build_cmd = "build"
source_dir = "packages"
build_dir = "dev_mode/static"
npm = ["node", "jupyterlab/staging/yarn.js"]

[tool.hatch.build.hooks.jupyter-builder.build-kwargs]
build_cmd = "build:prod:minimize"
path = "jupyterlab/staging"
source_dir = "jupyterlab/staging"
build_dir = "jupyterlab/static"
npm = ["node", "yarn.js"]

[tool.pytest.ini_options]
testpaths = "jupyterlab/tests"
norecursedirs = "node_modules .git _build .ipynb_checkpoints"
addopts = "--pdbcls=IPython.terminal.debugger:Pdb -v --junitxml=junit.xml"
ignore = "tests examples"

[tool.jupyter-releaser.options]
version-cmd = "jlpm bumpversion --force --skip-commit"
npm-install-options = "--legacy-peer-deps"
release-message = "[ci skip] Publish {version}"
tag-message = "[ci skip] Release {tag_name}"

[tool.jupyter-releaser.hooks]
before-bump-version = [
    "pip install -e .[dev]",
    "git checkout .",
]
before-build-npm = [
    "jlpm",
    "jlpm run build:all",
]
before-build-python = [
    "node buildutils/lib/local-repository start",
    "jlpm run before:build:python",
    "node buildutils/lib/local-repository stop",
]
after-publish-assets = "npm run after:publish:assets"

[tool.ruff]
target-version = "py38"
line-length = 100
select = [
  "A", "B", "C", "DTZ", "E", "EM", "F", "FBT", "I", "ICN", "N",
  "PLC", "PLE", "PLR", "PLW", "Q", "RUF", "S", "SIM", "T", "TID", "UP",
  "W", "YTT",
]
ignore = [
# Q000 Single quotes found but double quotes preferred
"Q000",
# FBT001 Boolean positional arg in function definition
"FBT001", "FBT002", "FBT003",
# E501 Line too long (158 > 100 characters)
"E501",
# PLR0913 Too many arguments to function call
"PLR0913",
# SIM105 Use `contextlib.suppress(...)`
"SIM105",
]

[tool.ruff.lint.per-file-ignores]
# F821 Undefined name `c`
"binder/jupyter_config.py" = ["F821"]
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
"examples/example_check.py" = ["RUF012"]
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
"examples/federated/main.py" = ["RUF012"]
# T201 `print` found
"examples/test_examples.py" = ["T201"]
# T201 `print` found
"galata/*" = ["T201"]
# F821 Undefined name `c`
# S104 Possible binding to all interfaces
# S105 Possible hardcoded password: `""`
"galata/jupyter_server_test_config.py" = ["F821", "S104", "S105"]
# T201 `print` found
"jupyterlab/browser_check.py" = ["RUF012", "T201"]
# C901 method is too complex
"jupyterlab/commands.py" = ["C901"]
# B028 No explicit `stacklevel` keyword argument found
"jupyterlab/debuglog.py" = ["B028"]
"jupyterlab/extensions/manager.py" = ["C901"]
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
# T201 `print` found
"jupyterlab/labapp.py" = ["RUF012", "T201"]
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
"jupyterlab/labextensions.py" = ["RUF012"]
# C901 method is too complex
# S101 Use of `assert` detected
# N802 Function name `foo` should be lowercase
# EM101 Exception must not use a string literal
# PLR2004 Magic value used in comparison
"jupyterlab/tests/*" = ["C901", "S101", "N802", "E501", "EM101", "EM102", "EM103", "PLR2004"]
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
"jupyterlab/tests/echo_kernel.py" = ["RUF012"]
# T201 `print` found
"scripts/milestone_check.py" = ["T201"]
# N806 Variable `tM` in function should be lowercase
# N816 Variable `comparatorTrimReplace` in global scope should not be mixedCase
# PLC1901 test can be simplified as an empty string is falsey
# PLR1714 Consider merging multiple comparisons
# PLR5501 Use `elif` instead of `else` then `if`, to reduce indentation
"jupyterlab/semver.py" = ["C901", "EM101", "EM102", "N806", "N816", "PLC1901", "PLR1714", "PLR5501"]
# T201 `print` found
"jupyterlab/upgrade_extension.py" = ["T201"]
# RUF012 Mutable class attributes should be annotated with `typing.ClassVar`
"packages/services/examples/node/main.py" = ["RUF012"]
# T201 `print` found
"scripts/i18n_check.py" = ["T201"]
